package com.maple.common.widget

import android.content.Context
import android.database.Observable
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import com.google.android.flexbox.FlexboxLayout


/**
 * Tip:
 * Create by SeVen on 2024/3/23 19:34
 */
class FlexboxLWidget @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FlexboxLayout(context, attrs, defStyleAttr) {

    private val mAdapterDataObserver: AdapterDataObserver = object : AdapterDataObserver() {
        override fun onChanged() {
            post {
                if (mAdapter != null) {
                    removeAllViews()
                    val total = mAdapter!!.itemCount
                    for (position in 0 until total) {
                        val v = mAdapter!!.onCreateView(this@FlexboxLWidget)
                        mAdapter!!.onBindView(v, position)
                        addView(v)
                    }
                }
            }
        }
    }
    private var mAdapter: Adapter? = null

    fun getAdapter(): Adapter? {
        return mAdapter
    }

    fun setAdapter(mAdapter: Adapter?) {
        if (mAdapter == null) {
            if (this.mAdapter != null) {
                this.mAdapter!!.mAdapterDataObservable.unregisterAll()
                this.mAdapter = null
            }
            removeAllViews()
        } else {
            if (this.mAdapter === mAdapter) {
                this.mAdapter!!.notifyDataSetChanged()
                return
            }
            this.mAdapter = mAdapter
            this.mAdapter!!.mAdapterDataObservable.registerObserver(mAdapterDataObserver)
            this.mAdapter!!.notifyDataSetChanged()
        }
    }


    abstract class Adapter {
        val mAdapterDataObservable = AdapterDataObservable()

        /**
         * 加载自定义布局
         *
         * @param parent 父容器
         * @return 自定义布局
         */
        abstract fun onCreateView(parent: ViewGroup?): View

        /**
         * 设置内容回调
         *
         * @param v        当前绑定视图
         * @param position 位置
         */
        abstract fun onBindView(v: View?, position: Int)

        /**
         * 获取总内容数
         *
         * @return 总数
         */
        abstract val itemCount: Int

        /**
         * 通知内容已更新
         */
        fun notifyDataSetChanged() {
            if (mAdapterDataObservable.hasObservers()) {
                mAdapterDataObservable.notifyChanged()
            }
        }
    }


    class AdapterDataObservable : Observable<AdapterDataObserver?>() {
        fun hasObservers(): Boolean {
            return mObservers.isNotEmpty()
        }

        fun notifyChanged() {
            for (i in mObservers.size - 1 downTo 0) {
                mObservers[i]?.onChanged()
            }
        }
    }


    abstract class AdapterDataObserver {
        abstract fun onChanged()
    }
}